package com.comment.service.Impl;

import DO.comments.CommentsDO;
import DTO.MQ.DeleteCommentDO;
import DTO.ReportCommentDTO;
import DTO.RootPageCommentDTO;
import DTO.TwoPageCommentDTO;
import VO.Feight.CommentUserMsgVO;
import VO.RootCommentVO;
import VO.TwoCommentVO;
import com.comment.mapper.CommentReportMapper;
import com.comment.mapper.CommentsMapper;
import com.comment.mapper.LikeCommentsMapper;
import com.comment.service.CommentService;
import Exception.CommentsIsNotExistException;
import Exception.UserNotExistException;
import Exception.NotIsTwoCommentException;
import com.feign.clients.UserClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import result.Result;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.utils.TimeUtils.formatTimeAgo;


@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentsMapper commentsMapper;

    @Autowired
    private LikeCommentsMapper likeCommentsMapper;

    @Autowired
    private UserClient userClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private CommentReportMapper commentReportMapper;


    /**
     * 用户回复
     * @param commentsDO
     */
    public void save(CommentsDO commentsDO) {
        commentsDO.setCreatedTime(LocalDateTime.now());

        // 1. 判断是否是顶级评论
        if (commentsDO.getIsFirst() == 1){
            // 顶级评论,减少不必要的开销
            commentsDO.setRootCommentsId(null);
            commentsDO.setToCommentId(null);
            commentsDO.setToCommentUserId(null);
        }else {
            // 利用toCommentId获取评论人的id
            commentsDO.setToCommentUserId(commentsMapper.getById(commentsDO.getToCommentId()).getUserId());
        }
        commentsMapper.save(commentsDO);
    }

    // 获取一级评论id
    public List<Integer> getRootId(RootPageCommentDTO rootPageCommentDTO) {
        List<Integer> rootIdByChat = commentsMapper.getRootIdByChat(rootPageCommentDTO);

        int index;
        if (rootPageCommentDTO.getLastCommentId() == 0){
            // 表示获取的是开始数据
            index = -1;
        }else {
            // 查找lastChatId在列表中的位置
            index = rootIdByChat.indexOf(rootPageCommentDTO.getLastCommentId());

            // 如果lastChatId不存在于列表中，返回空列表
            if (index == -1) {
                return new ArrayList<>();
            }
        }

        // 计算截取的开始位置（lastChatId的下一个位置）
        index++;

        // 计算需要截取的长度，确保不超过列表长度和请求的number
        int endIndex = Math.min(index + rootPageCommentDTO.getNumber(), rootIdByChat.size());

        // 截取列表并返回结果
        return rootIdByChat.subList(index, endIndex);
    }

    // 获取具体一级评论消息
    public RootCommentVO getRoot(Integer userId, Integer commentId) {
        CommentsDO commentsDO = commentsMapper.getById(commentId);
        // 评论不存在
        if (commentsDO == null){
            // 306 评论不存在
            throw new CommentsIsNotExistException();
        }
        RootCommentVO rootCommentVO = new RootCommentVO();
        rootCommentVO.setId(commentsDO.getId());
        rootCommentVO.setUserId(commentsDO.getUserId());
        rootCommentVO.setLikeNumber(commentsDO.getLikeNumber());
        rootCommentVO.setContent(commentsDO.getContent());
        rootCommentVO.setTime(formatTimeAgo(commentsDO.getCreatedTime()));
        // 二级评论数量
        rootCommentVO.setNumber(commentsMapper.getTwoNumber(commentId));

        // TODO 后面考虑是否缓存
        if (userId!=0){
            // 用户是否点赞
            Integer isLike = likeCommentsMapper.getIsLike(userId, commentId);
            rootCommentVO.setIsLike(isLike==null?0:isLike);
        }else {
            rootCommentVO.setIsLike(0);
        }

        // 远程调用，获取评论人信息 TODO 后面判断这里需不需要将这个缓存
        Result<CommentUserMsgVO> commentUserMsg = userClient.getCommentUserMsg(commentsDO.getUserId());
        if (commentUserMsg.getCode()==14){
            // 用户不存在，发帖人不存在
            throw new UserNotExistException();
        }
        rootCommentVO.setUsername(commentUserMsg.getData().getUsername());
        rootCommentVO.setAvatar(commentUserMsg.getData().getAvatar());

        return rootCommentVO;
    }

    // 获取二级评论id数组
    public List<Integer> getTwoId(TwoPageCommentDTO twoPageCommentDTO) {
        return commentsMapper.getTwoIds(twoPageCommentDTO);
    }

    // 二级评论的具体信息
    public TwoCommentVO getTwo(Integer userId, Integer commentId) {
        // 1. 先判断是不是
        TwoCommentVO twoCommentVO = new TwoCommentVO();
        CommentsDO commentsMapperById = commentsMapper.getById(commentId);
        if (commentsMapperById ==null){
            throw new CommentsIsNotExistException();
        }
        if (commentsMapperById.getIsFirst() == 1){
            throw new NotIsTwoCommentException();
        }
        twoCommentVO.setId(commentsMapperById.getId());
        twoCommentVO.setUserId(commentsMapperById.getUserId()); // 评论人id
        // 根据评论人id获取这个人的头像和昵称 远程调用
        Result<CommentUserMsgVO> commentUserMsg = userClient.getCommentUserMsg(commentsMapperById.getUserId());
        if (commentUserMsg.getCode() == 14){
            throw new UserNotExistException();
        }else if (commentUserMsg.getCode() == 200){
            twoCommentVO.setUsername(commentUserMsg.getData().getUsername());
            twoCommentVO.setAvatar(commentUserMsg.getData().getAvatar());
        }
        twoCommentVO.setLikeNumber(commentsMapperById.getLikeNumber());
        twoCommentVO.setContent(commentsMapperById.getContent());
        twoCommentVO.setTime(formatTimeAgo(commentsMapperById.getCreatedTime()));
        twoCommentVO.setRootCommentId(commentsMapperById.getRootCommentsId());
        twoCommentVO.setToCommentId(commentsMapperById.getToCommentId());
        twoCommentVO.setToCommentUserId(commentsMapperById.getToCommentUserId());

        // 远程调用获取回复目标人的昵称
        Result<CommentUserMsgVO> commentUserMsg1 = userClient.getCommentUserMsg(commentsMapperById.getToCommentUserId());
        if (commentUserMsg1.getCode() == 14){
            throw new UserNotExistException();
        }else if (commentUserMsg1.getCode() == 200){
            twoCommentVO.setToCommentUsername(commentUserMsg1.getData().getUsername());
        }


        // 判断用户是否点赞还是踩这个评论
        if (userId !=0){
            Integer isLike = likeCommentsMapper.getIsLike(userId, commentId);
            twoCommentVO.setIsLike(isLike==null?0:isLike);
        }else {
            twoCommentVO.setIsLike(0);
        }
        return twoCommentVO;
    }

    // 删除帖子相关的评论,
    public void MQdeleteByChat(Integer chatId) {
        List<Integer> IdList = commentsMapper.getByChat(chatId);
        commentsMapper.deleteByChat(chatId);
        for (Integer id : IdList) {
            likeCommentsMapper.deleteByCommentId(id);
        }
    }

    // 用户删除评论
    @Transactional
    public void deleteComment(Integer userId, Integer commentId) {
        CommentsDO commentsDO = commentsMapper.getById(commentId);
        if (commentsDO==null){
            throw new CommentsIsNotExistException();
        }
        if (!Objects.equals(commentsDO.getUserId(), userId)){
            // 表示不是本人操作 ,删除的不是自己发布的评论
            throw new UserNotExistException();
        }

        // 1. 删除评论
        int i = commentsMapper.deleteById(commentId);
        if (i==0){
            // 删除失败，抛出异常
            throw new CommentsIsNotExistException();
        }

        // 2. 判断是不是顶级评论
        int number = 0;
        if (commentsDO.getIsFirst()==1){
            // 是顶级评论，还需要删除顶级评论下的二级评论
            number = commentsMapper.deleteByRootId(commentId);
        }
        number = number + i;

        // 3. 发mq告诉chat服务，用户删除评论
        if (number==0){
            return;
        }
        DeleteCommentDO deleteCommentDO = new DeleteCommentDO();
        deleteCommentDO.setNumber(number);
        deleteCommentDO.setChatId(commentsDO.getChatId());
        try {
            rabbitTemplate.convertAndSend("ying.yan.omitComment", "chat.omitComment", deleteCommentDO);
        } catch (Exception e) {
            log.error("删除评论消息失败chatId:{},number:{}",deleteCommentDO.getChatId(),deleteCommentDO.getNumber());
        }

    }

    public void report(Integer userId, ReportCommentDTO reportCommentDTO) {
        CommentsDO commentsMapperById = commentsMapper.getById(reportCommentDTO.getCommentId());
        if (commentsMapperById == null){
            throw new CommentsIsNotExistException();
        }
        // 记录举报内容
        commentReportMapper.save(userId,reportCommentDTO.getCommentId(),reportCommentDTO.getContent(),commentsMapperById.getUserId(),commentsMapperById.getChatId());
    }
}
